package com.platform.security.mybatis;

import com.platform.common.annotation.logger.EnableLogger;
import com.platform.domain.result.TbSysResourceRole;
import com.platform.service.ResourcesService;
import org.apache.log4j.Logger;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import java.util.*;

public class PlatformFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @EnableLogger
    private static Logger logger;

    // 加载资源与权限的对应关系
    private ResourcesService resourcesService;

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    public PlatformFilterInvocationSecurityMetadataSource(ResourcesService resourcesService) {
        this.resourcesService = resourcesService;
    }

    // 由spring调用
    public PlatformFilterInvocationSecurityMetadataSource() {
        try {
            loadResourceDefine();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    //加载所有资源与权限的关系
    private void loadResourceDefine() throws Exception {
        if (resourceMap == null) {
            resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
            List<TbSysResourceRole> resources = resourcesService.queryAll();
            for (TbSysResourceRole resource : resources) {
                Collection<ConfigAttribute> configAttributes = resourceMap.get(resource.getResource());
                if (configAttributes == null) {
                    configAttributes = new ArrayList<ConfigAttribute>();
                }
                //以权限名封装为Spring的security Object
                ConfigAttribute configAttribute = new SecurityConfig(resource.getRoleId());
                configAttributes.add(configAttribute);
                resourceMap.put(resource.getResource(), configAttributes);
            }
        }

        Set<Map.Entry<String, Collection<ConfigAttribute>>> resourceSet = resourceMap.entrySet();
        Iterator<Map.Entry<String, Collection<ConfigAttribute>>> iterator = resourceSet.iterator();

    }

    //返回所请求资源所需要的权限
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        logger.info("requestUrl is " + requestUrl);
        if (resourceMap == null) {
            try {
                loadResourceDefine();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return resourceMap.get(requestUrl);
    }

}
